#include "myfile.h"

MY_FILE *my_fopen(const char *path, const char *mode)
{
    // 设置文件打开模式
    int flag = 0;
    if (strcmp(mode, "r") == 0)
        flag |= O_RDONLY;
    else if (strcmp(mode, "w") == 0)
        flag |= (O_WRONLY | O_CREAT | O_TRUNC);
    else if (strcmp(mode, "a") == 0)
        flag |= (O_WRONLY | O_CREAT | O_APPEND);
    if (strstr(mode, "+"))
        flag |= O_RDWR;
    else
    {
        // wb ...
    }
    // 根据路径打开文件
    umask(0);
    mode_t m = 0666;
    int fd = 0;
    if (flag & O_CREAT) // 读或追加的形式打开文件
    {
        fd = open(path, flag, m);
    }
    else
        fd = open(path, flag);
    if (fd < 0)
        return NULL; // 确保文件打开
    // 建立MY_FILE结构体
    MY_FILE *pf = (MY_FILE *)malloc(sizeof(MY_FILE)); // 开辟内存
    if (pf == NULL)
    {
        close(fd);   // 关闭文件
        return NULL; // 开辟失败返回
    }
    // 初始化结构体
    pf->fd = fd;
    pf->cur = 0;
    pf->mode = BUFF_LINE; // 默认为行刷新
    memset(pf->buffer, '\0', sizeof(pf->buffer));
    // 返回指针
    return pf;
}

void my_fllush(MY_FILE *fp)
{
    // 确保指针非空
    assert(fp);
    // 进行文件IO
    write(fp->fd, fp->buffer, fp->cur);
    // 清空缓冲区
    fp->cur = 0;
    fsync(fp->fd);
}

size_t my_fwrite(char *ptr, int size, int nmemb, MY_FILE *fp)
{
    // 确保传入的文件指针非空
    assert(fp);
    // 判断缓冲区的剩余空间
    size_t user_size = size * nmemb;
    size_t my_size = NUM - fp->cur;
    size_t writen = 0;
    // 空间已满,冲刷缓冲区
    if (my_size == NUM)
        my_fllush(fp);
    // 1.空间未满,直接写入
    if (my_size >= user_size)
    {
        memcpy(fp->buffer + fp->cur, ptr, user_size);
        fp->cur += user_size;
        writen = user_size;
    }
    // 2.空间未满,但无法写入全部内容,写入部分内容
    else
    {
        memcpy(fp->buffer + fp->cur, ptr, my_size);
        fp->cur += my_size;
        writen = my_size;
    }
    // 计划刷新
    if (fp->mode & BUFF_ALL) // 全缓冲
    {
        if (fp->cur == NUM)
            my_fllush(fp);
    }
    else if (fp->mode & BUFF_LINE) // 行缓冲
    {
        if (fp->buffer[fp->cur - 1] == '\n')
            my_fllush(fp);
    }
    else // 无缓冲
    {
    }
    // 结算写入的大小
    return writen / nmemb;
}

// size_t my_fread(char* ptr,int size,int nmemb,MY_FILE* fp)
// {
//     if(fp->cur) my_fllush(fp);  //缓冲区还有数据就要冲刷缓冲区

//     size_t usrsize = size*nmemb;
//     size_t mysize = NUM;

//     if(usrsize < mysize)  //读的大小小于缓冲区的大小
//     {
//         int len = read(fp->fd,fp->buffer,)
//     }

// }

void my_fclose(MY_FILE *fp)
{
    // 确保传入的不是空指针
    assert(fp);
    // 冲刷缓冲区
    if (fp->cur > 0)
        my_fllush(fp);
    // 关闭文件
    close(fp->fd);
    // 释放空间
    free(fp);
    // 指针置空
    fp = NULL;
}